import React, { Component } from 'react';
import PropTypes from 'prop-types';
import {
  FlatList,
  StyleSheet,
  Text,
  TextInput,
  View,
  TouchableOpacity,
  ViewPropTypes as RNViewPropTypes,
} from 'react-native';
import { Modal } from '@ant-design/react-native';
import { Container } from '@/rcomponents/Container';
//import { TouchableOpacity } from 'react-native-gesture-handler';
import { IconX } from '@/rcomponents/iconx';
import viewStyles from '@/rcomponents/viewStyles';
import Metrics from '@/Themes/Metrics';

// https://gist.github.com/tioback/6af21db0685cd3b1de28b84981f31cca

// Keep this line for downwards compatibility with RN.
const ViewPropTypes = RNViewPropTypes || View.propTypes;

function Dropdown({
  data,
  fliterValue,
  userStyle, //: {listStyle}
  keyExtractor,
  textExtractor,
  keyboardShouldPersistTaps = 'always',
  flatListProps,
  onSelect,
}) {
  let listData = data;
  if (fliterValue) {
    listData = listData.filter(
      (lsd) =>
        textExtractor(lsd).toLowerCase().indexOf(fliterValue.toLowerCase()) !==
        -1,
    );
  }
  const maxShowNum = 50;
  return (
    <FlatList
      style={[styles.list, userStyle.listStyle]}
      data={listData.slice(0, maxShowNum)}
      keyboardShouldPersistTaps={keyboardShouldPersistTaps}
      getItemLayout={(_, index) => ({
        length: 40,
        offset: 40 * index,
        index,
      })}
      renderItem={({ item }) => (
        <TouchableOpacity
          style={[styles.dropdownItemTouch]}
          onPress={() => {
            onSelect(item);
          }}
        >
          <Text style={styles.dropdownText}>{textExtractor(item)}</Text>
        </TouchableOpacity>
      )}
      ListEmptyComponent={
        <View style={[viewStyles.container, viewStyles.center, { margin: 20 }]}>
          <Text>未查到数据</Text>
        </View>
      }
      keyExtractor={keyExtractor || textExtractor}
      {...flatListProps}
    />
  );
}

class Autocomplete extends Component {
  static propTypes = {
    ...TextInput.propTypes,
    userStyle: PropTypes.shape({
      /**
       * 最外层view样式
       */
      containerStyle: ViewPropTypes.style,
      /*
       * 输入框样式
       */
      inputContainerStyle: ViewPropTypes.style,
      /**
       * 下拉列表样式
       */
      listStyle: ViewPropTypes.style,
    }),
    /**
     * 过滤列表数据
     */
    data: PropTypes.array,
    // 下拉列表属性
    flatListProps: PropTypes.object,
  };

  static defaultProps = {
    data: [],
    onStartShouldSetResponderCapture: () => false,
    renderSeparator: null,
    flatListProps: {},
  };

  constructor(props) {
    super(props);
    this.textInput = null;

    this.onRefTextInput = this.onRefTextInput.bind(this);
    this.onEndEditing = this.onEndEditing.bind(this);
    this.onBlur = this.onBlur.bind(this);
    this.onFocus = this.onFocus.bind(this);
    this.state = {
      showDropdown: false,
      inputVal: props.value,
      zIndex: 1,
    };
  }

  onEndEditing(e) {
    this.props.onEndEditing && this.props.onEndEditing(e);
  }

  onRefTextInput(textInput) {
    this.textInput = textInput;
  }

  onBlur() {
    this.setState({
      showDropdown: false,
      confirmClear: false,
      zIndex: this.state.zIndex - 1,
    });
  }

  onFocus() {
    this.setState({ showDropdown: true, zIndex: this.state.zIndex + 1 });
  }

  render() {
    const {
      data,
      placeholder,
      textExtractor,
      keyExtractor,
      keyboardShouldPersistTaps,
      userStyle = {},
      onComplete,
      flatListProps,
    } = this.props;
    const { showDropdown, confirmClear, inputVal, zIndex } = this.state;

    const inputView = (
      <View style={[styles.inputContainer, userStyle.inputContainerStyle]}>
        <TextInput
          style={[styles.input]}
          value={inputVal}
          ref={this.onRefTextInput}
          onEndEditing={this.onEndEditing}
          autoFocus={showDropdown}
          onFocus={this.onFocus}
          onBlur={this.onBlur}
          placeholder={placeholder}
          onChangeText={(text) => {
            const changed = {
              inputVal: text || '',
              //showDropdown: true,
            };
            //if (!text) {
            //  changed.showDropdown = false;
            //  if (onComplete) {
            //    onComplete({});
            //  }
            //}
            this.setState(changed);
          }}
        />
        {showDropdown && (
          <Container float="right">
            <TouchableOpacity
              style={styles.clearBtn}
              onPress={() => {
                this.setState({
                  inputVal: undefined,
                  confirmClear: confirmClear || inputVal !== undefined,
                });
                //this.textInput.blur();
              }}
            >
              <IconX size={20} origin="ant" name="closecircleo" />
            </TouchableOpacity>
          </Container>
        )}
      </View>
    );
    if (showDropdown) {
      const modalStyle = { height: '100%', marginTop: 30 };
      return (
        <Modal visible animationType="slide-up" style={modalStyle}>
          <View style={styles.modalInputContainer}>
            {inputView}
            <TouchableOpacity
              style={styles.cancelBtnContainer}
              onPress={() => {
                if (confirmClear && onComplete) {
                  onComplete({});
                }
                this.textInput.blur();
              }}
            >
              <Text style={styles.cancelBtnText}>
                {confirmClear ? '确定' : '取消'}
              </Text>
            </TouchableOpacity>
          </View>
          <Dropdown
            textExtractor={textExtractor}
            keyExtractor={keyExtractor}
            keyboardShouldPersistTaps={keyboardShouldPersistTaps}
            userStyle={userStyle}
            flatListProps={flatListProps}
            data={data}
            zIndex={zIndex}
            fliterValue={inputVal}
            onSelect={(item) => {
              this.setState({
                inputVal: textExtractor(item),
              });
              if (onComplete) {
                onComplete(item);
              }
              this.textInput.blur();
            }}
          />
        </Modal>
      );
    }
    return (
      <View
        style={[
          styles.container,
          userStyle.containerStyle,
          { zIndex, elevation: zIndex + 1 },
        ]}
      >
        {inputView}
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    zIndex: 1,
    elevation: 2,
  },
  inputContainer: {
    borderColor: '#b9b9b9',
    borderRadius: 1,
    borderWidth: 1,
    paddingHorizontal: 8,
    flex: 1,
    flexDirection: 'row',
    marginBottom: 0,
  },
  input: {
    backgroundColor: 'white',
    height: 40,
    flex: 2,
    fontSize: Metrics.sizes.size16,
  },
  list: {
    flex: 1,
    backgroundColor: 'white',
    borderTopWidth: 0,
  },
  clearBtn: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    //paddingRight: 5,
  },
  modalInputContainer: { flexDirection: 'row' },
  cancelBtnContainer: {
    justifyContent: 'center',
    padding: 10,
    borderWidth: 1,
    borderStartWidth: 0,
    borderTopColor: '#ddd',
    borderRightColor: '#ddd',
    borderBottomColor: '#ddd',
  },
  cancelBtnText: { fontSize: 16, color: '#108ee9' },
  dropdownItemTouch: {
    padding: 10,
    borderBottomWidth: 1,
    borderBottomColor: '#ddd',
    marginHorizontal: 10,
  },
  dropdownText: {
    fontSize: 18,
  },
});

export default Autocomplete;
